package com.sevenwonders.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.graphics.Color;

import com.sevenwonders.R;
import com.sevenwonders.core.Player.VictoryPointCategory;

public enum City {
    ALEXANDRIA("Alexandria", R.drawable.resource_glass) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.GLASS);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.LIGHTHOUSE_A1);
            phases.add(WonderPhase.LIGHTHOUSE_A2);
            phases.add(WonderPhase.LIGHTHOUSE_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.LIGHTHOUSE_B1);
            phases.add(WonderPhase.LIGHTHOUSE_B2);
            phases.add(WonderPhase.LIGHTHOUSE_B3);
            wonderPhases.put(Side.B, phases);
        }
    },
    BABYLON("Babylon", R.drawable.resource_clay) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.CLAY);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.HANGING_GARDENS_A1);
            phases.add(WonderPhase.HANGING_GARDENS_A2);
            phases.add(WonderPhase.HANGING_GARDENS_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.HANGING_GARDENS_B1);
            phases.add(WonderPhase.HANGING_GARDENS_B2);
            phases.add(WonderPhase.HANGING_GARDENS_B3);
            wonderPhases.put(Side.B, phases);
        }
    },
    EPHESUS("Ephesus", R.drawable.resource_papyrus) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.PAPYRUS);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.TEMPLE_OF_ARTEMIS_A1);
            phases.add(WonderPhase.TEMPLE_OF_ARTEMIS_A2);
            phases.add(WonderPhase.TEMPLE_OF_ARTEMIS_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.TEMPLE_OF_ARTEMIS_B1);
            phases.add(WonderPhase.TEMPLE_OF_ARTEMIS_B2);
            phases.add(WonderPhase.TEMPLE_OF_ARTEMIS_B3);
            wonderPhases.put(Side.B, phases);
        }
    },
    GIZA("Giza", R.drawable.resource_stone) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.STONE);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.PYRAMIDS_A1);
            phases.add(WonderPhase.PYRAMIDS_A2);
            phases.add(WonderPhase.PYRAMIDS_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.PYRAMIDS_B1);
            phases.add(WonderPhase.PYRAMIDS_B2);
            phases.add(WonderPhase.PYRAMIDS_B3);
            phases.add(WonderPhase.PYRAMIDS_B4);
            wonderPhases.put(Side.B, phases);
        }
    },
    HALICARNASSUS("Halicarnassus", R.drawable.resource_cloth) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.CLOTH);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.MAUSOLEUM_A1);
            phases.add(WonderPhase.MAUSOLEUM_A2);
            phases.add(WonderPhase.MAUSOLEUM_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.MAUSOLEUM_B1);
            phases.add(WonderPhase.MAUSOLEUM_B2);
            phases.add(WonderPhase.MAUSOLEUM_B3);
            wonderPhases.put(Side.B, phases);
        }
    },
    OLYMPIA("Olympia", R.drawable.resource_wood) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.WOOD);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.STATUE_OF_ZEUS_A1);
            phases.add(WonderPhase.STATUE_OF_ZEUS_A2);
            phases.add(WonderPhase.STATUE_OF_ZEUS_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.STATUE_OF_ZEUS_B1);
            phases.add(WonderPhase.STATUE_OF_ZEUS_B2);
            phases.add(WonderPhase.STATUE_OF_ZEUS_B3);
            wonderPhases.put(Side.B, phases);
        }
    },
    RHODES("Rhodes", R.drawable.resource_ore) {
        void awardStartingBonus(Player player) {
            player.addTradeableResource(Resource.ORE);
        }

        void setWonderPhases() {
            List<WonderPhase> phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.COLOSSUS_A1);
            phases.add(WonderPhase.COLOSSUS_A2);
            phases.add(WonderPhase.COLOSSUS_A3);
            wonderPhases.put(Side.A, phases);
            phases = new ArrayList<WonderPhase>();
            phases.add(WonderPhase.COLOSSUS_B1);
            phases.add(WonderPhase.COLOSSUS_B2);
            wonderPhases.put(Side.B, phases);
        }
    };

    public enum WonderPhase {
        COLOSSUS_A1(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        COLOSSUS_A2(Resource.CLAY, Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addMilitary(2);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.military, null));
                bonuses.add(new Bonus(R.drawable.military, null));
            }
        },
        COLOSSUS_A3(Resource.ORE, Resource.ORE, Resource.ORE, Resource.ORE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        COLOSSUS_B1(Resource.STONE, Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addMilitary(1);
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
                player.addMoney(3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.military, null));
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
                bonuses.add(new Bonus(R.drawable.coin, "3").textColor(Color.BLACK));
            }
        },
        COLOSSUS_B2(Resource.ORE, Resource.ORE, Resource.ORE, Resource.ORE) {
            void awardBonus(Player player) {
                player.addMilitary(1);
                player.addVictoryPoints(VictoryPointCategory.WONDER, 4);
                player.addMoney(4);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.military, null));
                bonuses.add(new Bonus(R.drawable.laurel, "4"));
                bonuses.add(new Bonus(R.drawable.coin, "4").textColor(Color.BLACK));
            }
        },
        HANGING_GARDENS_A1(Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        HANGING_GARDENS_A2(Resource.WOOD, Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addScience(Science.CHOOSE);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.science_tablet_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.science_compass_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.science_gear_small, null));
            }
        },
        HANGING_GARDENS_A3(Resource.CLAY, Resource.CLAY, Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        HANGING_GARDENS_B1(Resource.CLAY, Resource.CLOTH) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        HANGING_GARDENS_B2(Resource.WOOD, Resource.WOOD, Resource.GLASS) {
            void awardBonus(Player player) {
                // TODO: Player can play last card instead of discarding it
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.cards_checks, null));
            }
        },
        HANGING_GARDENS_B3(Resource.CLAY, Resource.CLAY, Resource.CLAY, Resource.PAPYRUS) {
            void awardBonus(Player player) {
                player.addScience(Science.CHOOSE);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.science_tablet_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.science_compass_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.science_gear_small, null));
            }
        },
        LIGHTHOUSE_A1(Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        LIGHTHOUSE_A2(Resource.ORE, Resource.ORE) {
            void awardBonus(Player player) {
                player.addComboResource(Resource.RAW);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.resource_clay_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_ore_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_wood_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_stone_small, null));
            }
        },
        LIGHTHOUSE_A3(Resource.GLASS, Resource.GLASS) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        LIGHTHOUSE_B1(Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addComboResource(Resource.RAW);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.resource_clay_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_ore_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_wood_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_stone_small, null));
            }
        },
        LIGHTHOUSE_B2(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addComboResource(Resource.MANUFACTURED);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.resource_glass_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_cloth_small, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.resource_papyrus_small, null));
            }
        },
        LIGHTHOUSE_B3(Resource.STONE, Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        MAUSOLEUM_A1(Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        MAUSOLEUM_A2(Resource.ORE, Resource.ORE, Resource.ORE) {
            void awardBonus(Player player) {
                // TODO:  Player immediately looks through discarded buildings and builds one for free
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.card_free_from_discard, null));
            }
        },
        MAUSOLEUM_A3(Resource.CLOTH, Resource.CLOTH) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        MAUSOLEUM_B1(Resource.ORE, Resource.ORE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 2);
                // TODO:  Player immediately looks through discarded buildings and builds one for free
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "2"));
                bonuses.add(new Bonus(R.drawable.card_free_from_discard, null));
            }
        },
        MAUSOLEUM_B2(Resource.CLAY, Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 1);
                // TODO:  Player immediately looks through discarded buildings and builds one for free
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "1"));
                bonuses.add(new Bonus(R.drawable.card_free_from_discard, null));
            }
        },
        MAUSOLEUM_B3(Resource.GLASS, Resource.PAPYRUS, Resource.CLOTH) {
            void awardBonus(Player player) {
                // TODO:  Player immediately looks through discarded buildings and builds one for free
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.card_free_from_discard, null));
            }
        },
        PYRAMIDS_A1(Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        PYRAMIDS_A2(Resource.WOOD, Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 5);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "5"));
            }
        },
        PYRAMIDS_A3(Resource.STONE, Resource.STONE, Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        PYRAMIDS_B1(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        PYRAMIDS_B2(Resource.STONE, Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 5);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "5"));
            }
        },
        PYRAMIDS_B3(Resource.CLAY, Resource.CLAY, Resource.CLAY) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 5);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "5"));
            }
        },
        PYRAMIDS_B4(Resource.STONE, Resource.STONE, Resource.STONE, Resource.STONE, Resource.PAPYRUS) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        STATUE_OF_ZEUS_A1(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        STATUE_OF_ZEUS_A2(Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                // TODO:  Once per age, Player may build a building for free
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.card_free, null));
            }
        },
        STATUE_OF_ZEUS_A3(Resource.ORE, Resource.ORE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        STATUE_OF_ZEUS_B1(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                // TODO:  Check for this Wonder Phase when doing commerce
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.arrow_left_small, null));
                bonuses.add(new Bonus(R.drawable.trading_post, null));
                bonuses.add(new Bonus(R.drawable.arrow_right_small, null));
            }
        },
        STATUE_OF_ZEUS_B2(Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 5);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "5"));
            }
        },
        STATUE_OF_ZEUS_B3(Resource.ORE, Resource.ORE, Resource.CLOTH) {
            void awardBonus(Player player) {
                // TODO:  Receive the bonus of one of your neighbor's Guilds
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.card_purple, null));
                bonuses.add(new Bonus(R.drawable.arrow_left, null));
                bonuses.add(new Bonus(R.drawable.slash, null));
                bonuses.add(new Bonus(R.drawable.arrow_right, null));
            }
        },
        TEMPLE_OF_ARTEMIS_A1(Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
            }
        },
        TEMPLE_OF_ARTEMIS_A2(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addMoney(9);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.coin, "9").textColor(Color.BLACK));
            }
        },
        TEMPLE_OF_ARTEMIS_A3(Resource.PAPYRUS, Resource.PAPYRUS) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 7);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "7"));
            }
        },
        TEMPLE_OF_ARTEMIS_B1(Resource.STONE, Resource.STONE) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 2);
                player.addMoney(4);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "2"));
                bonuses.add(new Bonus(R.drawable.coin, "4").textColor(Color.BLACK));
            }
        },
        TEMPLE_OF_ARTEMIS_B2(Resource.WOOD, Resource.WOOD) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 3);
                player.addMoney(4);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "3"));
                bonuses.add(new Bonus(R.drawable.coin, "4").textColor(Color.BLACK));
            }
        },
        TEMPLE_OF_ARTEMIS_B3(Resource.PAPYRUS, Resource.CLOTH, Resource.GLASS) {
            void awardBonus(Player player) {
                player.addVictoryPoints(VictoryPointCategory.WONDER, 5);
                player.addMoney(4);
            }

            protected void setBonuses() {
                bonuses.add(new Bonus(R.drawable.laurel, "5"));
                bonuses.add(new Bonus(R.drawable.coin, "4").textColor(Color.BLACK));
            }
        };

        public class Bonus {
            private int resourceId;
            private String displayText;
            private int textColor = Color.WHITE;

            public Bonus(int resourceId, String displayText) {
                this.resourceId = resourceId;
                this.displayText = displayText;
            }

            public int getResourceId() {
                return resourceId;
            }

            public String getDisplayText() {
                return displayText;
            }

            public int getTextColor() {
                return textColor;
            }

            public Bonus textColor(int textColor) {
                this.textColor = textColor;
                return this;
            }
        }

        private List<Resource> cost = new ArrayList<Resource>();
        protected List<Bonus> bonuses = new ArrayList<Bonus>();
        private boolean completed = false;

        private WonderPhase(Resource... resources) {
            for (Resource resource : resources) {
                cost.add(resource);
            }

            setBonuses();
        }

        public List<Resource> getCost() {
            return cost;
        }

        public List<Bonus> getBonuses() {
            return bonuses;
        }

        protected abstract void setBonuses();

        boolean isCompleted() {
            return completed;
        }

        void setCompleted(boolean completed) {
            this.completed = completed;
        }

        abstract void awardBonus(Player player);
    }

    public enum Side {
        A('A'),
        B('B');

        private char letter;

        private Side(char letter) {
            this.letter = letter;
        }

        public char getLetter() {
            return letter;
        }
    }

    private String name;
    private int startingBonusId;
    private Side side = Side.A;
    protected Map<Side, List<WonderPhase>> wonderPhases = new HashMap<Side, List<WonderPhase>>();

    private City(String name, int startingBonusId) {
        this.name = name;
        this.startingBonusId = startingBonusId;
        setWonderPhases();
    }

    public String getName() {
        return name;
    }

    public int getStartingBonusId() {
        return startingBonusId;
    }

    public Map<Side, List<WonderPhase>> getWonderPhases() {
        return wonderPhases;
    }

    public List<WonderPhase> getWonderPhasesForSide() {
        return wonderPhases.get(side);
    }

    public Side getSide() {
        return side;
    }

    public void setSide(Side side) {
        this.side = side;
    }

    abstract void awardStartingBonus(Player player);

    abstract void setWonderPhases();
}
